#ifndef _SYS_UTILS_H
#define _SYS_UTILS_H
#ifdef __cplusplus
extern "C"
{
#endif  /* __cplusplus */
#include <stdint.h>
#include <string.h>

/*----------------------------------------------------------------------------*/
extern const char n_map_ascii[16];

#define u8_to_ascii_LSB(_u8,_byte) do\
{ \
	(_byte)[0] = n_map_ascii[(_u8) & 0x0F]; \
	(_byte)[1] = n_map_ascii[(_u8 >> 4) & 0x0F]; \
} while(0)
#define u8_to_ascii_MSB(_u8,_byte) do\
{ \
	(_byte)[0] = n_map_ascii[(_u8 >> 4) & 0x0F]; \
	(_byte)[1] = n_map_ascii[(_u8) & 0x0F]; \
} while(0)
#define u16_to_ascii_LSB(_u16,_byte) do\
{ \
	(_byte)[0] = n_map_ascii[(_u16) & 0x0F]; \
	(_byte)[1] = n_map_ascii[(_u16 >> 4) & 0x0F]; \
	(_byte)[2] = n_map_ascii[(_u16 >> 8) & 0x0F]; \
	(_byte)[3] = n_map_ascii[(_u16 >> 12) & 0x0F]; \
} while(0)
#define u16_to_ascii_MSB(_u16,_byte) do\
{ \
	(_byte)[0] = n_map_ascii[(_u16 >> 12) & 0x0F]; \
	(_byte)[1] = n_map_ascii[(_u16 >> 8) & 0x0F]; \
	(_byte)[2] = n_map_ascii[(_u16 >> 4) & 0x0F]; \
	(_byte)[3] = n_map_ascii[(_u16) & 0x0F]; \
} while(0)

/*----------------------------------------------------------------------------*/
#define byte_to_u16_LSB(_pbyte) ((((uint16_t)(_pbyte)[1])<<8) | (_pbyte)[0])
#define byte_to_u16_MSB(_pbyte) ((((uint16_t)(_pbyte)[0])<<8) | (_pbyte)[1])

#define byte_to_u32_LSB(_pbyte) ((((uint32_t)(_pbyte)[3])<<24) | \
		(((uint32_t)(_pbyte)[2])<<16) | \
		(((uint32_t)(_pbyte)[1])<<8) | \
		(_pbyte)[0])
#define byte_to_u32_MSB(_pbyte) ((((uint32_t)(_pbyte)[0])<<24) | \
		(((uint32_t)(_pbyte)[1])<<16) | \
		(((uint32_t)(_pbyte)[2])<<8) | \
		(_pbyte)[3])

#define byte3_to_u32_LSB(_pbyte) ((((uint32_t)(_pbyte)[2])<<16) | \
		(((uint32_t)(_pbyte)[1])<<8) | \
		(_pbyte)[0])
#define byte3_to_u32_MSB(_pbyte) ((((uint32_t)(_pbyte)[0])<<16) | \
		(((uint32_t)(_pbyte)[1])<<8) | \
		(_pbyte)[2])

#define u16_to_byte_LSB(_u16,_pbyte) do\
{ \
	(_pbyte)[0] = (uint8_t)(((_u16)) & 0xFF); \
	(_pbyte)[1] = (uint8_t)(((_u16) >> 8) & 0xFF); \
} while(0)
#define u16_to_byte_MSB(_u16,_pbyte) do\
{ \
	(_pbyte)[0] = (uint8_t)(((_u16) >> 8) & 0xFF); \
	(_pbyte)[1] = (uint8_t)(((_u16)) & 0xFF); \
} while(0)

#define u32_to_byte_LSB(_u32,_pbyte) do\
{ \
	(_pbyte)[0] = (uint8_t)(((_u32)) & 0xFF); \
	(_pbyte)[1] = (uint8_t)(((_u32) >> 8) & 0xFF); \
	(_pbyte)[2] = (uint8_t)(((_u32) >> 16) & 0xFF); \
	(_pbyte)[3] = (uint8_t)(((_u32) >> 24) & 0xFF); \
} while(0)
#define u32_to_byte_MSB(_u32,_pbyte) do\
{ \
	(_pbyte)[0] = (uint8_t)(((_u32) >> 24) & 0xFF); \
	(_pbyte)[1] = (uint8_t)(((_u32) >> 16) & 0xFF); \
	(_pbyte)[2] = (uint8_t)(((_u32) >> 8) & 0xFF); \
	(_pbyte)[3] = (uint8_t)(((_u32)) & 0xFF); \
} while(0)

#define u32_to_byte3_LSB(_u32,_pbyte) do\
{ \
	(_pbyte)[0] = (uint8_t)(((_u32)) & 0xFF); \
	(_pbyte)[1] = (uint8_t)(((_u32) >> 8) & 0xFF); \
	(_pbyte)[2] = (uint8_t)(((_u32) >> 16) & 0xFF); \
} while(0)
#define u32_to_byte3_MSB(_u32,_pbyte) do\
{ \
	(_pbyte)[0] = (uint8_t)(((_u32) >> 16) & 0xFF); \
	(_pbyte)[1] = (uint8_t)(((_u32) >> 8) & 0xFF); \
	(_pbyte)[2] = (uint8_t)(((_u32)) & 0xFF); \
} while(0)

/*----------------------------------------------------------------------------*/
uint8_t byte_to_bcd2(uint8_t value);
uint8_t bcd2_to_byte(uint8_t value);
uint16_t bin_to_bcd4(uint16_t bin);
uint16_t bcd4_to_bin(uint16_t bcd4);
uint32_t bin_to_bcd8(uint32_t bin);
uint32_t bcd8_to_bin(uint32_t bcd8);
uint64_t bin_to_bcd16(uint64_t bin);
uint64_t bcd16_to_bin(uint64_t bcd16);

/*----------------------------------------------------------------------------*/
int char_to_bin(char *s, int len, int *bin);
int char_to_double(char *s, int len, double *dval);
int hex_to_char(uint8_t *hex, uint16_t len, char *buff, uint16_t size);
int char_to_hex(char *s, int len, uint8_t *hex);

typedef struct
{
	char *key;
	char *val;
} kv_t;

int char_lower(char *s, int len);
int char_upper(char *s, int len);
int char_strcasestr_i(char *s, char *d);
char *char_strcasestr(char *s, char *d);
int char_strcasecmp(char *s, char *d);
char *char_trim(char *s, int len);
int char_kv(char *s, char *delim, kv_t *kv);
int char_argv(char *s, int len, char *delim, char **argv, int n);
int char_to_hhmm(char *s, uint32_t *hhmm);

int buff_cmp(void *ptr1, void *ptr2, int len, int ignore);
uint16_t buffer_append(void *buffer, uint16_t off, uint16_t size, char *s);
uint16_t buffer_copy(char *buffer, uint16_t size, char *s);
uint16_t buffer_cat(char *buffer, uint16_t size, char *s);

int hex2char(uint8_t *hex, uint16_t len, char *str, int size);

/*----------------------------------------------------------------------------*/
uint16_t MODBUS_crc16(uint8_t *buff, uint16_t len);

#define CRC16_CCIT_FAST (1)
#define CRC16_CCIT_VAL_INIT (0xFFFF)
uint16_t crc16_ccit_calc(uint16_t crc16, uint8_t *data, uint16_t len);
uint16_t crc16_ccit_calc_s(uint8_t *data, uint16_t len);

/*----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif  /* __cplusplus */
#endif /* _SYS_UTILS_H */

